#include "flash.h"
#include "stm32f10x_flash.h"

/**
  * @brief  Flash初始化
  * @param  None
  * @retval Flash_Status_TypeDef 操作状态
  */
Flash_Status_TypeDef Flash_Init(void)
{
    /* 解锁Flash */
    FLASH_Unlock();
    
    /* 清除所有标志位 */
    FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);
    
    return FLASH_OP_SUCCESS;
}

/**
  * @brief  擦除Flash页
  * @param  page_addr: 页地址
  * @retval Flash_Status_TypeDef 操作状态
  */
Flash_Status_TypeDef Flash_EraseDataPage(uint32_t page_addr)
{
    FLASH_Status flash_status;
    
    /* 擦除页 */
    flash_status = FLASH_ErasePage(page_addr);
    
    if(flash_status == FLASH_COMPLETE)
    {
        return FLASH_OP_SUCCESS;
    }
    else
    {
        return FLASH_OP_ERROR;
    }
}

/**
  * @brief  向Flash写入数据
  * @param  addr: 写入地址
  * @param  data: 数据指针
  * @param  len: 数据长度
  * @retval Flash_Status_TypeDef 操作状态
  */
Flash_Status_TypeDef Flash_WriteData(uint32_t addr, uint8_t *data, uint16_t len)
{
    FLASH_Status flash_status = FLASH_COMPLETE;
    uint16_t i;
    uint16_t *data_16 = (uint16_t*)data;
    uint16_t len_16 = (len + 1) / 2;  // 转换为16位长度
    
    /* 按16位写入 */
    for(i = 0; i < len_16; i++)
    {
        flash_status = FLASH_ProgramHalfWord(addr + i * 2, data_16[i]);
        if(flash_status != FLASH_COMPLETE)
        {
            return FLASH_OP_ERROR;
        }
    }
    
    return FLASH_OP_SUCCESS;
}

/**
  * @brief  从Flash读取数据
  * @param  addr: 读取地址
  * @param  data: 数据指针
  * @param  len: 数据长度
  * @retval Flash_Status_TypeDef 操作状态
  */
Flash_Status_TypeDef Flash_ReadData(uint32_t addr, uint8_t *data, uint16_t len)
{
    uint16_t i;
    
    for(i = 0; i < len; i++)
    {
        data[i] = *(uint8_t*)(addr + i);
    }
    
    return FLASH_OP_SUCCESS;
}

/**
  * @brief  保存DHT11数据到Flash (覆盖模式)
  * @param  dht11_data: DHT11数据指针
  * @param  timestamp: 时间戳
  * @retval Flash_Status_TypeDef 操作状态
  */
Flash_Status_TypeDef DHT11_Flash_SaveData(DHT11_Data_TypeDef *dht11_data, uint32_t timestamp)
{
    DHT11_Flash_Data_TypeDef flash_data;
    Flash_Status_TypeDef status;
    
    /* 每次保存前先擦除页面 */
    status = Flash_EraseDataPage(FLASH_DATA_START_ADDR);
    if(status != FLASH_OP_SUCCESS)
    {
        return status;
    }
    
    /* 填充数据结构 */
    flash_data.timestamp = timestamp;
    flash_data.humi_int = dht11_data->humi_int;
    flash_data.humi_deci = dht11_data->humi_deci;
    flash_data.temp_int = dht11_data->temp_int;
    flash_data.temp_deci = dht11_data->temp_deci;
    flash_data.check_sum = dht11_data->check_sum;
    flash_data.valid_flag = 0xAA;  // 标记为有效数据
    flash_data.reserved[0] = 0x00;
    flash_data.reserved[1] = 0x00;
    
    /* 写入Flash到固定地址 */
    status = Flash_WriteData(DHT11_SINGLE_RECORD_ADDR, (uint8_t*)&flash_data, sizeof(flash_data));
    
    return status;
}

/**
  * @brief  从Flash读取最新的DHT11数据
  * @param  flash_data: 读取数据指针
  * @retval Flash_Status_TypeDef 操作状态
  */
Flash_Status_TypeDef DHT11_Flash_ReadLatestData(DHT11_Flash_Data_TypeDef *flash_data)
{
    /* 从固定地址读取数据 */
    return Flash_ReadData(DHT11_SINGLE_RECORD_ADDR, (uint8_t*)flash_data, sizeof(DHT11_Flash_Data_TypeDef));
}

/**
  * @brief  检查Flash中是否有有效的DHT11数据
  * @param  None
  * @retval uint8_t 1=有有效数据, 0=无有效数据
  */
uint8_t DHT11_Flash_HasValidData(void)
{
    DHT11_Flash_Data_TypeDef flash_data;
    
    if(DHT11_Flash_ReadLatestData(&flash_data) == FLASH_OP_SUCCESS)
    {
        return (flash_data.valid_flag == 0xAA) ? 1 : 0;
    }
    
    return 0;
}

/**
  * @brief  擦除DHT11数据
  * @param  None
  * @retval Flash_Status_TypeDef 操作状态
  */
Flash_Status_TypeDef DHT11_Flash_EraseData(void)
{
    /* 擦除数据页 */
    return Flash_EraseDataPage(FLASH_DATA_START_ADDR);
}
